/*
 * Copyright (C) 拾光分享网
 * All rights reserved, Designed By www.hiai.top.
 * Email：goodsking@163.com.
 */
package top.hiai.my.favorite;

import com.jfinal.kit.Ret;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.IAtom;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Page;
import top.hiai.common.account.UserService;
import top.hiai.common.model.Favorite;
import top.hiai.common.model.User;

import java.sql.SQLException;
import java.util.Date;

/**
 * @Author www.hiai.top
 * @Email goodsking@163.com
 * @Message 更多资源尽在www.hiai.top
 * @Introduction 类的介绍
 */
@SuppressWarnings("rawtypes")
public class MyFavoriteService {

    public static final MyFavoriteService me = new MyFavoriteService();
    private Favorite favoriteDao = new Favorite().dao();

    /**
     * 遍历用户收藏的文章
     *
     * @param pageNum
     * @param pageSize
     * @param uid
     * @return
     */
    public Page<Favorite> userArticleFavoritePage(int pageNum, int pageSize, int uid) {
        String select = " select f.id,f.accountId,f.refType,f.refId,f.addtime,a.aid,a.title,a.uid ";
        String from = " from bbs_favorite as f , bbs_article as a where f.accountId=? and f.refId=a.aid and f.refType=1 order by addtime desc ";

        Page<Favorite> favoriteList = favoriteDao.paginate(pageNum, pageSize, select, from, uid);
        UserService.me.join("uid", favoriteList.getList(), "nickName", "avatar");
        return favoriteList;
    }

    /**
     * 遍历用户收藏的话题分类
     *
     * @param pageNum
     * @param pageSize
     * @param uid
     * @return
     */
    public Page<Favorite> userCommentsFavoritePage(int pageNum, int pageSize, int uid) {
        //查找到用户收藏的分类
        //查找到用户收藏的分类，并统计该分类下面有多少文章
        String select = "select f.id,f.accountId,f.refType,f.refId,f.addtime ,c.name,c.tid,c.images";
        String from = " from  bbs_favorite as f,bbs_comments as c where f.accountId=? and f.refType=2 and f.refId = c.tid  ";
        Page<Favorite> favoriteList = favoriteDao.paginate(pageNum, pageSize, select, from, uid);
        return favoriteList;
    }

    /**
     * 对 refType + refId 指向的资源，是否已收藏
     */
    public boolean isFavorite(int accountId, int refType, int refId) {
        String sql = "select accountId from bbs_favorite where accountId=? and refType=? and refId=? limit 1";
        return Db.queryInt(sql, accountId, refType, refId) != null;
    }

    /**
     * 设置 article detail 页面的收藏状态
     *
     * @param loginAccount 登录的用户
     * @param refTypeTable 收藏的类型，是收藏的文章还是收藏的话题
     * @param refObj       文章就传入Article 话题就是Comments
     * @param ret          ret.返回信息
     */
    public void setFavoriteStatus(User loginAccount, String refTypeTable, Model refObj, Ret ret) {
        if (loginAccount != null) {
            boolean isFavorite = false;
            /**
             * 这个地方是一个坑，因为的数据表设计的主键ID名字不一样，所有要区分一下。
             * 如果您的主键一样，这里就可以去掉了，只用查找表的ID
             */
            if (refTypeTable.equals("comments")) {
                isFavorite = isFavorite(loginAccount.getUid(), Favorite.getRefType(refTypeTable), refObj.getInt("tid"));
            } else if (refTypeTable.equals("article")) {
                isFavorite = isFavorite(loginAccount.getUid(), Favorite.getRefType(refTypeTable), refObj.getInt("aid"));
            }
            ret.set("isFavoriteActive", isFavorite ? "active" : "");
            ret.set("isFavoriteAdd", isFavorite ? "false" : "true");
        } else {
            ret.set("isFavoriteActive", "");
            ret.set("isFavoriteAdd", "true");
        }
        int favoriteCount = refObj.getInt("favoriteCount");
        ret.set("favoriteCount", favoriteCount > 0 ? favoriteCount : "0");
    }

    /**
     * 删除 文章 时，要删除相关的收藏
     *
     * @param aid
     */
    public void deleteByArticleDeleted(int aid) {
        deleteByRefDeleted(Favorite.REF_TYPE_ARTICLE, aid);
    }

    /**
     * 删除被引用的资源时，要删除相关的收藏
     *
     * @param refType 收藏的类型
     * @param refId   收藏的帖子ID
     */
    private void deleteByRefDeleted(int refType, int refId) {
        Db.update("delete from bbs_favorite where refType=? and refId=?", refType, refId);
    }

    /**
     * 收藏
     *
     * @param myId         收藏的用户 id，即当前登录用户
     * @param refTypeTable 被收藏的表名
     * @param refId        被收藏的表名中的相应的 id 值
     * @param isAdd        true 为收藏，false 为取消收藏，null 需要判断是否已被收藏
     */
    public Ret favoriteAdd(int myId, String refTypeTable, int refId, Boolean isAdd) {
        Favorite.checkRefTypeTable(refTypeTable);
        if (isAdd != null) {
            if (isAdd) {
                if (refTypeTable.equals("article")) {
                    return saveArticle(myId, refTypeTable, refId);
                } else {
                    return saveComments(myId, refTypeTable, refId);
                }
            } else {
                return delete(myId, refTypeTable, refId);
            }
        } else {
            return favorite(myId, refTypeTable, refId);
        }
    }

    /**
     * 添加收藏这里不接受isAdd，也就是不判断是收藏还是取消收藏
     * 好处是只能做一种单个操作
     *
     * @param myId
     * @param refTypeTable
     * @param refId
     * @return
     */
    private Ret favorite(int myId, String refTypeTable, int refId) {
        String sql = "select accountId from bbs_favorite where accountId=? and refType=? and refId=? limit 1";
        if (Db.queryInt(sql, myId, Favorite.getRefType(refTypeTable), refId) != null) {
            return delete(myId, refTypeTable, refId);
        } else {
            return saveArticle(myId, refTypeTable, refId);
        }
    }

    /**
     * 获取被收藏资源的创建者
     *
     * @param refTypeTable
     * @param refId
     * @return
     */
    private Integer getUserIdOfRef(String refTypeTable, int refId) {
        return Db.queryInt("select uid from bbs_" + refTypeTable + " where aid=? limit 1", refId);
    }

    /**
     * 添加文章收藏
     *
     * @param myId
     * @param refTypeTable
     * @param refId
     * @return
     */
    private Ret saveArticle(final int myId, final String refTypeTable, final int refId) {
        //获取被收藏资源的创建者
        final Integer userId = getUserIdOfRef(refTypeTable, refId);
        if (myId == userId) {
            return Ret.fail().set("msg", "不能收藏自己的文章");
        }
        if (Db.queryInt("select accountId from bbs_favorite where accountId=? and refType=? and refId=? limit 1",
                myId, Favorite.getRefType(refTypeTable), refId) != null) {
            return Ret.fail().set("msg", "已经收藏过该文章");
        }
        boolean isOk = Db.tx(new IAtom() {
            public boolean run() throws SQLException {
                int n = Db.update("insert into bbs_favorite(accountId, refType, refId, addtime) values(?, ?, ?, ?)",
                        myId, Favorite.getRefType(refTypeTable), refId, new Date());
                if (n > 0) {
                    n = Db.update("update bbs_article set favoriteCount=favoriteCount+1 where aid=? limit 1", refId);
                }
                return n > 0;
            }
        });
        return isOk ? Ret.ok() : Ret.fail().set("msg", "收藏失败");
    }

    /**
     * 添加分类话题收藏
     * 区域与收藏文章时候会判断是否是自己的文章
     *
     * @param myId
     * @param refTypeTable
     * @param refId
     * @return
     */
    private Ret saveComments(final int myId, final String refTypeTable, final int refId) {
        boolean isOk = Db.tx(new IAtom() {
            public boolean run() throws SQLException {
                int n = Db.update("insert into bbs_favorite(accountId, refType, refId, addtime) values(?, ?, ?, ?)",
                        myId, Favorite.getRefType(refTypeTable), refId, new Date());
                if (n > 0) {
                    n = Db.update("update bbs_comments set favoriteCount=favoriteCount+1 where tid=? limit 1", refId);
                }
                return n > 0;
            }
        });
        return isOk ? Ret.ok() : Ret.fail().set("msg", "收藏失败");
    }

    /**
     * 取消收藏
     *
     * @param myId
     * @param refTypeTable
     * @param refId
     * @return
     */
    private Ret delete(final int myId, final String refTypeTable, final int refId) {
        boolean isOk = Db.tx(new IAtom() {
            public boolean run() throws SQLException {
                int n = Db.update("delete from bbs_favorite where accountId=? and refType=? and refId=? limit 1", myId, Favorite.getRefType(refTypeTable), refId);
                if (n > 0) {
                    if (refTypeTable.equals("comments")) {
                        n = Db.update(" update bbs_comments set favoriteCount=favoriteCount-1 where tid=? and favoriteCount>0 limit 1", refId);
                    } else if (refTypeTable.equals("article")) {
                        n = Db.update(" update bbs_article set favoriteCount=favoriteCount-1 where aid=? and favoriteCount>0 limit 1", refId);
                    }
                }
                return n > 0;
            }
        });
        return isOk ? Ret.ok() : Ret.fail().set("msg", "取消收藏失败");
    }

}